# -*- coding:utf-8 -*-

from pymongo import UpdateOne
import tushare as ts
from pe.util.DataBase import DB_CONN
from pe.util.StockUtil import getAllCodes
import urllib3
import json

"""
从东财获取财务数据，保存到数据库中
"""
class FinanceReportCrawler:

    def __init__(self):
        self.db = DB_CONN

    """
    从东方财富网站抓取三张财务报表
    :return:
    """
    def crawlFinanceReport(self):
        # 先获取所有的股票列表
        codes = getAllCodes()

        # 创建连接池
        connPool = urllib3.PoolManager()

        # 抓取的网址，两个替换参数{1}-财报类型 {2}-股票代码
        url = 'http://dcfm.eastmoney.com/em_mutisvcexpandinterface/api/js/get?' \
              'type={1}&token=70f12f2f4f091e459a279469fe49eca5&' \
              'st=reportdate&sr=-1&p=1&ps=500&filter=(scode=%27{2}%27)' \
              '&js={%22pages%22:(tp),%22data%22:%20(x)}&rt=51044775#'

        userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36'

        # 对应的类型，分别为资产负债表、现金流量表、利润表
        reportTypes = ['CWBB_ZCFZB', 'CWBB_XJLLB', 'CWBB_LRB']

        for code in codes:
            for reportType in reportTypes:
                print('开始抓取财报数据， 股票： %s, 财报类型: %s' % (code, reportType), flush=True)
                response = connPool.request('GET',
                                            url.replace('{1}', reportType).replace('{2}', code),
                                            headers={
                                                'User-Agent': userAgent
                                            })

                # 解析抓取结果
                result = json.loads(response.data.decode('UTF-8'))
                reports = result['data']

                updateRequests = []
                for report in reports:
                    # 更新字段端
                    try:
                        report.update({
                            # 公告日期和报告日期只保留年月日
                            'announced_date': report['noticedate'][0:10],
                            'report_date': report['reportdate'][0:10],
                            # 股票名称和股票代码的字段名和系统设计保持一致
                            'code': code,
                            'name': report['sname']
                        })

                        updateRequests.append(
                            UpdateOne({
                                'code': code,
                                'report_date': report['report_date'],
                                'announced_date': report['announced_date'],
                                },
                                {'$set': report},
                                upsert=True
                            )
                        )
                    except:
                        print('解析出错，股票：%s 财报类型：%s' % (code, reportType))

                if len(updateRequests) > 0:
                    updateResult = self.db[reportType].bulk_write(updateRequests, ordered=False)
                    print('股票 %s, 财报类型: %s, 更新：%4d, 新增： %4d' % (code, reportType, updateResult.modified_count, updateResult.upserted_count))

    """
    获取回测周期内的年度财报数据，组合成一个dict数据结构，key是股票代码，
    value是一个按照报告发布日期排序的列表，列表内的元素也是一个dict
    {'eps': 每股收益, 'announced_date': 公告日期}
    """
    def getCodeReports(self):

        # 这个tuple包含了三个元素，前两个分别是用来获取年度财报时的参数年份和季度，
        # 后面是一个发布年度财报的年份，因为一般情况下发布财报都是在第二年的4月底之前，
        # 所以这个年份比财报的年份晚一年
        